package com.connector.server.server;

import org.slf4j.LoggerFactory;
import com.connector.server.redis.OnLineUserCache;
import com.connector.base.connection.impl.NettyConnection;
import com.connector.base.connection.Connection;
import com.connector.base.connection.channel.SocketChannel;
import com.connector.base.connection.channel.NettyChannelSocketChannel;
import com.connector.base.protocol.Packet;
import io.netty.channel.ChannelHandlerContext;
import com.connector.base.message.PacketReceiver;
import com.connector.base.connection.ConnectionRegistry;
import org.slf4j.Logger;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInboundHandlerAdapter;

@ChannelHandler.Sharable
public class ServerChannelHandler extends ChannelInboundHandlerAdapter
{
    private static final Logger log;
    private final ConnectionRegistry connectionRegistry;
    private final PacketReceiver receiver;
    
    public ServerChannelHandler(final ConnectionRegistry connectionRegistry, final PacketReceiver receiver) {
        this.connectionRegistry = connectionRegistry;
        this.receiver = receiver;
    }
    
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
        final Packet packet = (Packet)msg;
        final Connection connection = this.connectionRegistry.get((SocketChannel)new NettyChannelSocketChannel(ctx.channel()));
        ServerChannelHandler.log.debug("channelRead conn={},packet={}", new Object[] { ctx.channel(), connection.getSessionContext(), msg });
        connection.updateLastReadTime();
        this.receiver.onReceive(packet, connection);
    }
    
    public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
        final Connection connection = this.connectionRegistry.get((SocketChannel)new NettyChannelSocketChannel(ctx.channel()));
        ServerChannelHandler.log.error("caught an ex, channel={}, conn={}", new Object[] { ctx.channel(), connection, cause });
        ctx.close();
    }
    
    public void channelActive(final ChannelHandlerContext ctx) throws Exception {
        ServerChannelHandler.log.info("serverclient connected conn={}", (Object)ctx.channel());
        final Connection connection = (Connection)new NettyConnection();
        connection.init((SocketChannel)new NettyChannelSocketChannel(ctx.channel()));
        this.connectionRegistry.add(connection);
    }
    
    public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
        final Connection connection = this.connectionRegistry.removeAndClose((SocketChannel)new NettyChannelSocketChannel(ctx.channel()));
        if (null != connection && null != connection.getSessionContext()) {
            final String userId = connection.getSessionContext().getUserId();
            OnLineUserCache.del(userId);
            ServerChannelHandler.log.info("服务器主动连接断开:{}", (Object)userId);
        }
        else {
            ServerChannelHandler.log.info("服务器主动连接断开");
        }
    }
    
    static {
        log = LoggerFactory.getLogger((Class)ServerChannelHandler.class);
    }
}
